package com.baoteng.rbspy.util;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.baoteng.rbspy.model.DateTime;

public class BaseUtil {

	public static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	
    private static final String[] MobilePrefix= "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153".split(","); 
    
    public static final String RB_SERKEY="cifencode";
    
    
    public static void main(String[] args) {
    	String r = "您录入的车型与平台返回的车型不一致，请核实车辆信息是否准确或提交电子联系单处理！\n平台返回的车型如下: \n 品牌名称：上汽通用五菱\n车系名称：荣光\n车款名称：五菱LZW6450BCF\n";
		System.out.println(r.substring(r.lastIndexOf("：")+1).replaceAll("\n", "")+"1");
	}
    /**
     * 通过统一社会信用代码获取组织机构代码
     * @return
     */
    public static String getOrgCodeBySocialCode(String cocialCode) {
    	if(StringUtils.isBlank(cocialCode) || cocialCode.length()!=18){
			return cocialCode;
		}
    	return cocialCode.substring(8, cocialCode.length()-1);
    }
    
    /**
	 * 去除中午，保留字母、数字、半角标点。
	 * 不能已标点开头
	 * @param str
	 * @return
	 */
    public static String matchNumberAndLetters(String orginal){
		if(StringUtils.isBlank(orginal)){
			return orginal;
		}
		String result = orginal.replaceAll("[^\\w|\\s|\\p{Punct}]","");
		return result.replaceAll("^\\pP","");
	}
    
    public static String dateTime2String(DateTime datetime,String fromat) {
    	return com.baoteng.rbspy.util.DateUtils.dateToString(new Date(datetime.getTime()), fromat);
    }
    
    public static String dateTime2String(DateTime datetime) {
    	return com.baoteng.rbspy.util.DateUtils.dateToString(new Date(datetime.getTime()), "yyyy-MM-dd");
    }
    
    /**
     * 加密手机号码
     * @return
     */
    public static String encodeRbPhoneMobile(String mobile) {
    	StringBuilder result = new StringBuilder();

    	for(int i=0,j=0;i<mobile.length();i++,j++){
    		if(j == RB_SERKEY.length()){
    			j = 0;
    		}
    		int uc= mobile.charAt(i)^RB_SERKEY.charAt(j);
    		result.append(String.format("%03d", uc));
    	}
    	return result.toString();
    }
    
    /**
     * 解密手机号码
     * @return
     */
    public static String decodeRbPhoneMobile(String encodeStr) {
        StringBuilder result = new StringBuilder();
        for(int i=0,j=0;i<encodeStr.length()/3;i++,j++){
            if(j == RB_SERKEY.length()){
                j = 0;
            }
            result.append((char)(Integer.parseInt(encodeStr.substring(i*3,i*3+3))^RB_SERKEY.charAt(j)));
        }
        return result.toString();
    }

    public static String getRandomMobile() {  
        String first=MobilePrefix[getRandomNum(0,MobilePrefix.length-1)];  
        String second=String.valueOf(getRandomNum(1,888)+10000).substring(1);  
        String third=String.valueOf(getRandomNum(1,9100)+10000).substring(1);  
        return first+second+third;  
    }
    
    public static String getRandomTel(String prefix) {  
        String second=String.valueOf(getRandomNum(1,888)+10000).substring(1);  
        String third=String.valueOf(getRandomNum(1,9100)+10000).substring(1);  
        return prefix+second+third;  
    }
    
	public static int getRandomNum(int start,int end) {  
        return (int)(Math.random()*(end-start+1)+start);  
    }
	
	/**
	 * 处理宝马大小写不一致
	 * 
	 * @param modelName
	 * @return
	 */
	public static String modelNameHandler(String modelName) {
		if (StringUtils.isNotBlank(modelName) && modelName.contains("宝马BMW") && !"宝马BMW".equals(modelName.trim())) {
			char[] array = modelName.toCharArray();
			if (array[array.length - 1] >= 'a' && array[array.length - 1] <= 'z'
					|| array[array.length - 1] >= 'A' && array[array.length - 1] <= 'Z') {
				Integer index = null;
				for (int i = array.length - 1; i > -1; i--) {
					if (!(array[i] >= 'a' && array[i] <= 'z') && !(array[i] >= 'A' && array[i] <= 'Z')) {
						index = i;
						break;
					}
				}
				if (index != null) {
					modelName = new StringBuilder().append(modelName.substring(0, index))
							.append(modelName.substring(index).toLowerCase()).toString();
				}
			}
		}
		return modelName;
	}

	/**
	 * vin码转换成车型查询码，
	 */
	public static String getQueryCodeByVIN(String vin) {
		if (StringUtils.isBlank(vin) || vin.length() != 17)
			return null;
		return StringUtils.join(vin.substring(0, 8), vin.substring(9, 11));
	}

	/**
	 * 从字符串中解析日期字符串，如果有多个，返回时间最大的日期
	 * 
	 * @param content
	 * @return
	 */
	public static Date parseMaxDateFromStr(String content) {
		if (StringUtils.isBlank(content)) {
			return null;
		}
		Pattern p = Pattern.compile("(\\d{1,4}-\\d{1,2}-\\d{1,2})", Pattern.MULTILINE);
		Matcher matcher = p.matcher(content);
		Date result = null;
		while (matcher.find()) {
			if (result == null) {
				try {
					result = DateUtils.parseDate(matcher.group(), "yyyy-MM-dd");
				} catch (ParseException e) {
					e.printStackTrace();
				}
			} else {
				try {
					Date _result = DateUtils.parseDate(matcher.group(), "yyyy-MM-dd");
					if (_result.getTime() > result.getTime()) {
						result = _result;
					}
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}

	/**
	 * 将Date类转换为XMLGregorianCalendar
	 * 
	 * @param date
	 * @return
	 */
	public static XMLGregorianCalendar dateToXmlDate(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		DatatypeFactory dtf = null;
		try {
			dtf = DatatypeFactory.newInstance();
		} catch (DatatypeConfigurationException e) {
		}
		XMLGregorianCalendar dateType = dtf.newXMLGregorianCalendar();
		dateType.setYear(cal.get(Calendar.YEAR));
		// 由于Calendar.MONTH取值范围为0~11,需要加1
		dateType.setMonth(cal.get(Calendar.MONTH) + 1);
		dateType.setDay(cal.get(Calendar.DAY_OF_MONTH));
		dateType.setHour(cal.get(Calendar.HOUR_OF_DAY));
		dateType.setMinute(cal.get(Calendar.MINUTE));
		dateType.setSecond(cal.get(Calendar.SECOND));
		return dateType;
	}

	/**
	 * 将XMLGregorianCalendar转换为Date
	 * 
	 * @param cal
	 * @return
	 */
	public static Date xmlDate2Date(XMLGregorianCalendar cal) {
		return cal.toGregorianCalendar().getTime();
	}

	public static Date getDefaultInsureStartDate() {
		return DateUtils.addDays(DateUtils.truncate(new Date(), Calendar.DATE), 1);
	}

	public static Date getInsureEndDate(Date startDate) {
		return DateUtils.addSeconds(DateUtils.addYears(startDate, 1), -1);
	}

	/**
	 * 保险到期时间计算保险起期
	 * 
	 * @param startDate
	 * @return
	 */
	public static Date getInsureStartDate(Date startDate) {
		return DateUtils.addSeconds(DateUtils.addYears(startDate, -1), 1);
	}

	/**
	 * 到期时间计算下年保险起期
	 * 
	 * @param startDate
	 * @return
	 */
	public static Date getNextInsureStartDateByExpireDate(Date expireDate) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(DateUtils.addMinutes(expireDate, 1));
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getInsureEndDay(Date startDate) {
		return DateUtils.addDays(DateUtils.addYears(startDate, 1), -1);
	}

	/**
	 * 9座以下计算公式 计算折损中使用————计算两个时间的相间月份->通用
	 *
	 * @param enddate
	 * @param startdate
	 * @return
	 */
	private int CalDiffMonth_9seatBelow(String enddate, String startdate) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		int months = 0;
		try {
			Date enddateTemp = format.parse(enddate);
			Date startdateTemp = format.parse(startdate);
			if (enddateTemp.getYear() < startdateTemp.getYear())
				return 0;
			months += (enddateTemp.getYear() - startdateTemp.getYear()) * 12;
			months += (enddateTemp.getMonth() - startdateTemp.getMonth());
			int day = enddateTemp.getDay() - startdateTemp.getDay();
			if (day <= 0) {
				months--;
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return months;
	}

	/**
	 * 9座以下计算公式 //车损盗抢,结束时间,开始时间 计算折损折扣->通用(重庆平安车损盗抢公式一样)
	 *
	 * @param purchasePrice
	 * @param enddate
	 * @param startdate
	 * @return
	 */
	private double CalVehicleDepreciationPrice_9seatBelow(String purchasePrice, String enddate, String startdate) {
		DecimalFormat df = new DecimalFormat("#.000");
		double purchasePriceTemp = Double.parseDouble(purchasePrice);
		double monthDepreciationRate = 0.006;
		int months = CalDiffMonth_9seatBelow(enddate, startdate);
		double rate = months * monthDepreciationRate;
		double currentPrice = purchasePriceTemp * (1 - rate);
		if (currentPrice < purchasePriceTemp * 0.2) {
			return Double.parseDouble(df.format(purchasePriceTemp * 0.2));
		}
		return Double.parseDouble(df.format(currentPrice));
	}

	/**
	 * 9座以上(包含9座)计算公式 //计算两个日期（精确到天）之间相差多少个月，不足一月不算
	 *
	 * @param enddate
	 * @param startdate
	 * @return
	 */
	private int CalDiffMonth_9seatAbove(String startdate, String enddate) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		int months = 0;
		try {
			Date enddateTemp = format.parse(enddate);
			Date startdateTemp = format.parse(startdate);
			Date tmpDate;
			if (enddateTemp.getTime() > startdateTemp.getTime()) {
				tmpDate = enddateTemp;
				enddateTemp = startdateTemp;
				startdateTemp = tmpDate;
			}
			months = (enddateTemp.getYear() - startdateTemp.getYear()) * 12;
			months += (enddateTemp.getMonth() + 1) - (startdateTemp.getMonth() + 1);// 月份从0开始

			if (enddateTemp.getDate() < startdateTemp.getDate()) {
				months--;
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return months;
	}

	/**
	 * 货车车损险算法 9座以上(包含9座)计算公式
	 *
	 * @param purchasePrice
	 * @param enrollDate
	 * @param calDate
	 * @param useNature
	 * @param vehicleType
	 * @param useNatureCode
	 * @return
	 */
	private double TruckDepreciationPrice_9seatAbove(String purchasePrice, String enrollDate, String calDate,
			String useNature, String vehicleType, String useNatureCode) {
		String tmpPurchasePrice = purchasePrice;
		double monthDepreciationRate = 0.009;
		if ("1".equals(useNature) && ("A012".equals(vehicleType) || "A022".equals(vehicleType))) {
			monthDepreciationRate = 0.012;
		} else if ("2".equals(useNature) && ("A012".equals(vehicleType) || "A022".equals(vehicleType))) {
			monthDepreciationRate = 0.006;
		}
		if ("1".equals(useNature) && "01".equals(useNatureCode)) {
			monthDepreciationRate = 0.011;
		}
		int months = CalDiffMonth_9seatAbove(enrollDate, calDate);
		double rate = months * monthDepreciationRate;
		double currentPrice = Double.parseDouble(tmpPurchasePrice) * (1.00 - rate);
		if (currentPrice < Double.parseDouble(purchasePrice) * 0.2) {
			return Double.parseDouble(purchasePrice) * 0.2;
		}
		return currentPrice;
	}

	/**
	 * 计算车辆实际价值
	 * 
	 * @param blProposal
	 * @throws Exception
	 */
	private String calCarActualValueForCCIC() throws Exception {

		return null;
	}

	// public static void main(String[] args){
	// System.out.println(BaseUtil.discount(DateUtils.parseDate("2016-12-22"),
	// DateUtils.parseDate("2010-01-14"), 105800d, 2, 5));
	// System.out.println(new Date().getTime());
	// }

	/**
	 * 获取车辆使用年限
	 * 大于等于9个月算一年
	 * 
	 * @return
	 */
	public static int carUseYears(Date bizStartDate, Date regDate) {
		if (regDate==null || bizStartDate ==null || bizStartDate.before(regDate)) {
			return 0;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(bizStartDate);
		int yearBiz = cal.get(Calendar.YEAR);
		int monthBiz = cal.get(Calendar.MONTH);
		int dayBiz = cal.get(Calendar.DAY_OF_MONTH);
		cal.setTime(regDate);
		int yearReg = cal.get(Calendar.YEAR);
		int monthReg = cal.get(Calendar.MONTH);
		int dayReg = cal.get(Calendar.DAY_OF_MONTH);
		int month = (yearBiz - yearReg) * 12 + monthBiz - monthReg + (dayBiz < dayReg ? -1 : 0);
		if (month < 9) {
			return 0;
		} else {
			return month/12+(month%12<9?0:1);
		} 
	}

	/**
	 * 车损险、盗抢险、自燃险保额 折旧计算方法 使用性质 车辆种类 是否是租赁车 折扣 营业 六座以下客车和六座到十座以下客车 否 0.012 非营业
	 * 六座以下客车和六座到十座以下客车 否 0.006 营业 是 0.011 其他 其他 其他 0.009
	 * 月份计算=商业险开始日期与初登日期相差月份数，不足月不算 折旧费=新车购置价（不含税价格）*（1-（月份计算*折扣））
	 * 注：折旧费不能小于新车购置价（不含税价）的0.2折小于时取新车购置价（不含税价）的0.2折
	 * 
	 */
	public static double discount(Date bizStartDate, Date regDate, double priceNoTax, Integer useNature,
			int seatCount) {
		// 缺省默认2
		if (useNature == null) {
			useNature = 2;
		}
		if (priceNoTax <= 0)
			return 0;
		double discount = 0;
		if (useNature == 1) {
			if (seatCount < 9) {
				discount = 0.012;
			} else {
				discount = 0.011;
			}
		} else if (useNature == 2 && seatCount <= 9) {
			discount = 0.006;
		} else {
			discount = 0.009;
		}
		double minDiscount = 0.2;
		double minCount = priceNoTax * minDiscount;
		Calendar cal = Calendar.getInstance();
		cal.setTime(bizStartDate);
		int yearBiz = cal.get(Calendar.YEAR);
		int monthBiz = cal.get(Calendar.MONTH);
		int dayBiz = cal.get(Calendar.DAY_OF_MONTH);
		cal.setTime(regDate);
		int yearReg = cal.get(Calendar.YEAR);
		int monthReg = cal.get(Calendar.MONTH);
		int dayReg = cal.get(Calendar.DAY_OF_MONTH);
		int month = (yearBiz - yearReg) * 12 + monthBiz - monthReg + (dayBiz < dayReg ? -1 : 0);
		double count = priceNoTax * (1 - ((month < 0 ? 0 : month) * discount));
		count = count < minCount ? minCount : count;
		DecimalFormat df1 = new DecimalFormat("#0.00");
		return Double.valueOf(df1.format(count));
	}

	public static double getMoneyNumber(double amount) {
		DecimalFormat df1 = new DecimalFormat("#0.00");
		return Double.valueOf(df1.format(amount));
	}

	public static double getFormatNumber(double amount, int scale) {
		DecimalFormat df1 = new DecimalFormat(StringUtils.join("#0.", StringUtils.repeat("0", scale)));
		return Double.valueOf(df1.format(amount));
	}

	public static Date getBirthdayByAge(int age) {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.YEAR, -age);
		return DateUtils.truncate(c.getTime(), Calendar.DATE);
	}

	public static Date getRandomBirthday() {
		long date = System.currentTimeMillis();
		try {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			Date startDate = format.parse("1950-01-01");
			Date endDate = format.parse("2000-01-01");
			date = startDate.getTime() + (long) (Math.random() * (startDate.getTime() - endDate.getTime()));
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return new Date(date);
	}

	public static int getAge(Date birthday) {
		Calendar cal = Calendar.getInstance();

		if (cal.before(birthday)) {
			return 0;
		}
		int yearNow = cal.get(Calendar.YEAR);
		int monthNow = cal.get(Calendar.MONTH);
		int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
		cal.setTime(birthday);

		int yearBirth = cal.get(Calendar.YEAR);
		int monthBirth = cal.get(Calendar.MONTH);
		int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

		int age = yearNow - yearBirth;

		if (monthNow <= monthBirth) {
			if (monthNow == monthBirth) {
				if (dayOfMonthNow < dayOfMonthBirth)
					age--;
			} else {
				age--;
			}
		}
		return age;
	}

	/**
	 * 
	 * @param idNo
	 * @return 1--女 2--男
	 */
	public static Integer getSexByID(String idNo) {
		if (StringUtils.isBlank(idNo) || idNo.length() != 18) {
			return null;
		}
		String sex = idNo.substring(16, 17);
		try {
			if (Integer.parseInt(sex) % 2 == 0) {
				return 1;
			} else {
				return 2;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Date getBirthdayByID(String idNo) {
		if (StringUtils.isBlank(idNo) || idNo.length() != 18) {
			return null;
		}
		try {
			String year = idNo.substring(6, 10);
			String month = idNo.substring(10, 12);
			String day = idNo.substring(12, 14);
			StringBuilder sb = new StringBuilder();
			sb.append(year);
			sb.append("-");
			sb.append(month);
			sb.append("-");
			sb.append(day);

			Date birthday = DateUtils.parseDate(sb.toString(), "yyyy-MM-dd");
			return birthday;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// public static String generateString(int length) {
	// String baseCode = Long.toHexString(System.nanoTime());
	// if (baseCode.length() >= length) {
	// return baseCode.substring(0, length);
	// }
	// StringBuffer sb = new StringBuffer();
	// sb.append(RandomStringUtils.random(length - baseCode.length(),
	// BaseUtil.ALLCHAR.toCharArray()));
	// sb.append(baseCode);
	// return sb.toString();
	// }

	public static String addDayByString(String strDate, int amount) throws Exception {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		Date date = formatter.parse(strDate);
		DateUtils.addDays(date, 1);
		return formatter.format(date);
	}

	public static String date2String(Date date, String pattern) {
		return org.apache.commons.lang3.time.DateFormatUtils.format(date, pattern);
	}

}
